import { isObject, isArray, isString, isNull, isUndefined } from "is-type-data";
import { shallowMerge } from "./merge";
import eventCallbacks from "./lowcode/eventCallbacks";

const renderStringData = (str, data) => {
  if (!data) return str;
  return str.replace(/\${\w+}/g, (m) => {
    const value = data[m.slice(2, -1)];
    return value;
  });
};

function handleDataChain(schema, parentData) {
  schema.config.data = shallowMerge(parentData, schema.config.data);
}

const getCustomEventCallback = (event) => {
  let executor = () => {};
  const { name } = event.executor;
  if (Array.isArray(name)) {
    name.forEach((item, i) => {
      if (i === 0) {
        executor = eventCallbacks[item];
      } else {
        executor = executor[item];
      }
    });
  } else {
    executor = eventCallbacks["service"];
  }

  return executor;
};

function bindingInput(form, name) {
  return (value) => {
    form[name] = value;
  };
}

const formControls = [
  "el-input",
  "aegle-input",
  "aegle-select",
  "el-date-picker",
  "aegle-radio",
];

function handleVModel(tag, config, form) {
  if (formControls.includes(tag)) {
    const { name } = config;
    if (name) {
      if (!config.on) config.on = {};
      config.on.input = bindingInput(form, name);
      config.on.modelValue = bindingInput(form, name);
      config.props.value = form[name];
    }
  }
}

export default function renderFormSchema(schema, h, parentData) {
  // 处理数据链
  handleDataChain(schema, parentData);

  const { tag, config, children, events, __scopedSlots } = schema;
  const { data } = config;

  // 基本组件的双向绑定
  // handleVModel(tag, config, this.__form);

  // 挂载事件

  if (isArray(events)) {
    events.forEach((event) => {
      if (!config.on) {
        config.on = {};
      }

      const { eventName } = event;
      config.on[eventName] = async () => {
        const fn = getCustomEventCallback(event);
        console.log(event.executor.params);
        return fn.call(this, event.executor.params);
      };
    });
  }

  // 处理插槽
  const scopedSlots = (config && config.scopedSlots) || {};
  if (__scopedSlots) {
    for (let key in __scopedSlots) {
      const schema = __scopedSlots[key];

      scopedSlots[key] = (props) =>
        renderFormSchema.call(this, schema, h, props);
    }

    config.scopedSlots = scopedSlots;
  }

  // 使用 h 进行vnode生成

  // 有子元素的处理
  if (isString(children)) {
    return h(tag, config, renderStringData(children, data));
  } else if (isArray(children) && children.length) {
    const childrenVnodes = children.map((child) => {
      if (isString(child)) {
        return renderStringData(child, data);
      }
      return renderFormSchema.call(this, child, h, data);
    });
    return h(tag, config, childrenVnodes);
  }

  // 当没有子元素时的处理
  return h(tag, config);
}
